#include "gateway_protocol.h"
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp> 
#include <boost/regex.hpp>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/algorithm/hex.hpp>
#include "../tool/cbase64.h"
#include "../../liblog/Include/liblog.h"
#include<stdio.h>
struct _nameText
{
	const char* name;		//属性名
	const char* unit;		//属性单位
    const char* desc;		//属性描述
    const char* valtype;    //属性值类型
};

//该结构体成员有顺序性
static const _nameText g_NameText[] =
{
{"srcdata","","原始数据帧","\""},
{"rssi", "", "当前数据包信号指示", ""},
{"mac", "", "设备 IMEI", "\""},
{"rorg", "", "数据帧类型码", "\""},
{"func", "", "插座(排插)", "\""},
{"type", "", "功能分类Default(“01”)", "\""},
{"sn", "", "帧号HEX", ""},
{"ticks", "10ms", "当前数据包生成的系统tick时间", ""},
{"vt", "V", "电压", ""},
{"current", "A", "电流", ""},
{"watt", "", "有功功率", ""},
{"wkh", "", "总电量", ""},
{"factor", "", "功率因素", ""},
{"frelay", "", "负载通断状态", "\""},
{"remoteaddr", "", "远端地址", "\""},
{"localaddr", "", "本地地址", "\""},
{"retime", "s", "上报间隔", ""}, //与下面ctr_retime变量值一致
//{"ip", "", "中心IP", "\""},
//{"port", "", "中心端口", ""},
//{"sw", "", "通断", ""} //与下面ctr_sw变量值一致
};

const char* ctr_retime = "retime";
const char* ctr_sw = "frelay";

gateway_protocol::gateway_protocol(std::string ip, int port)
{
    m_strbuf.clear();
    m_devid.clear();
    m_state.srcdata.clear();
    m_state.rssi.clear();
    m_state.mac.clear();
    m_state.rorg.clear();
    m_state.func.clear();
    m_state.type.clear();
    m_state.sn.clear();
    m_state.ticks.clear();
    m_state.vt.clear();
    m_state.current.clear();
    m_state.watt.clear();
    m_state.wkh.clear();
    m_state.factor.clear();
    m_state.frelay.clear();
    m_state.localaddr.clear();
    m_ip = ip;
    m_port = port;
    m_state.remoteaddr = ip + std::string(":") + boost::lexical_cast<std::string>(port);
    //m_state.ip = ip;
    //m_state.port = boost::lexical_cast<std::string>(port);
    m_state.retime = "\"-\"";
    //m_state.sw = "\"-\"";
}

int gateway_protocol::init(std::string ip, int port)
{
    m_ip = ip;
    m_port = port;
    //m_state.ip = ip;
    m_state.remoteaddr = ip + std::string(":") + boost::lexical_cast<std::string>(port);
    m_state.retime = "\"-\"";
    //m_state.sw = "\"-\"";

    boost::property_tree::ptree reader;
	boost::property_tree::ini_parser::read_ini("collectionsvr.ini", reader);
	m_ip = reader.get<std::string>("centerip.CENTER_IP"); //一定要是外网IP
    m_port = reader.get<int>("centerip.CENTER_PORT");//一定要是外网端口
    m_state.localaddr = m_ip + std::string(":") + boost::lexical_cast<std::string>(m_port);
    return 0;
}

int gateway_protocol::prase(const unsigned char* data, int datalen)
{
    if (!data)
        return -1;
    //^\$sdata (-[1-9]\d+) ([0-9]){15} (a5) (23) ([0-9a-zA-Z])* ([0-9a-fA-F]{1,2}) (\d+) (\d+.\d+) (\d+.\d+) (\d+.\d+) (\d+.\d+) (\d+.\d+) (0|1) \n
    static boost::regex rule("^\\$sdata (-[1-9]\\d+) ([0-9]{15}) (a5) (23) ([0-9a-zA-Z])* ([0-9a-fA-F]{1,2}) (\\d+) (\\d+.\\d+) (\\d+.\\d+) (\\d+.\\d+) (\\d+.\\d+) (\\d+.\\d+) (0|1) \\n");
    std::string protoText((char*)data, datalen);
    boost::smatch what;
    if (!boost::regex_match(protoText, what, rule))
        return -1;

    boost::smatch::iterator it = what.begin();
    unsigned int len = (it->str().length() + 2) / 3 * 4;
	char* strbase64 = new char[len];
	CBase64::Encoder((const unsigned char*)it->str().c_str(), it->str().length(), strbase64, len);
    m_state.srcdata = std::string(strbase64, len);
    delete []strbase64;
    ++it;
    for (int i = 1; it != what.end(); ++it)
    {
        std::string *str = (std::string*)((char*)&m_state + sizeof(std::string) * (i++));
        *str = it->str();
    }
    return 0;
}

std::string gateway_protocol::get_json_buf()
{
    return make_json(&m_state);
}

std::string gateway_protocol::make_json(StateInfo* state)
{
    if (!state)
        return "";

    std::string strjsonbuf = "{";
    int count = sizeof(g_NameText) / sizeof(_nameText);
    for (int i = 0; i < count; i++)
    {
        std::string *str = (std::string*)((char*)state + sizeof(std::string) * i);
        LogDebug(("%s(%s):%s\r\n", g_NameText[i].desc, g_NameText[i].name, (*str).c_str()));  
        std::string strtmp = "";
        if (i != 6)
        {
            strtmp = std::string("\"") + std::string(g_NameText[i].name) + std::string("\":") 
            + std::string(g_NameText[i].valtype) + *str + std::string(g_NameText[i].valtype) + std::string(",");
        }  
        else{//处理sn，是16进制变味10进制
            int isn = 0;
            sscanf(str->c_str(), "%x", &isn);
            boost::format fmt("%s");
            fmt % isn;
            strtmp = std::string("\"") + std::string(g_NameText[i].name) + std::string("\":") 
            + std::string(g_NameText[i].valtype) + fmt.str() + std::string(g_NameText[i].valtype) + std::string(",");  
        }
        strjsonbuf += strtmp;
        
    }
    strjsonbuf.replace(strjsonbuf.length() - 1, 1, "}");//去掉最后一个‘,’
    return strjsonbuf;
}

int gateway_protocol::make()
{
    return 0;
}

std::string gateway_protocol::get_devid()
{
    return m_state.mac;
}


std::string gateway_protocol::get_ctrcmddata(std::string strkey, std::string strval)
{
    std::string strcmd = "";
    if (strkey.compare(std::string(ctr_retime)) == 0) //设置上报时间间隔,（连带着设置中心IP地址，故中心ip地址在配置文件中必须要设置好）
    {
        m_state.retime = strval;
        strcmd = std::string("$send d1 64 01 01 16 1 ") + strval + std::string(" ") + m_ip + std::string(" ") + boost::lexical_cast<std::string>(m_port) + std::string(" \n");
    }
    else if (strkey.compare(std::string(ctr_sw)) == 0)
    {
        if (strval.compare("0") != 0 && strval.compare("1") != 0)//值只能为"1"或者"0"
            return "";
        m_state.frelay = strval;
        strcmd = std::string("$send d1 90 01 01 ") + strval + std::string(" \n");
    }

    return strcmd;
}


int gateway_protocol::get_retime()
{
    if (m_state.retime.compare("\"-\"") == 0)
        return -1;

    int time = boost::lexical_cast<int>(m_state.retime);
    if (time <= 0)
        return -1;
    return time;
}